#pragma once
#include "wlroots.hpp"
#include "utils.h"
#include "server.h"

#include <sigc++/sigc++.h>

#include <list>
#include <array>

#define BWL_NR_LAYERS (4)

class OutputWrapper
{
public:
    OutputWrapper(struct wlr_output* output, Server* server);
    ~OutputWrapper();

    inline struct wlr_output *output() { return m_wlr_output; }
    bool is_usable();

    sigc::signal<void()> sig_destroy;

private:
    void output_destroy();
    void output_frame(void *data);
    void output_request_state(void *data);

    void add_to_layout();
    void do_output_layout_change();

    bool get_tearing_preference();

private:
    Server *m_server;

    // wl_listener_wrapper m_link; /* server.outputs */
    struct wlr_output *m_wlr_output;
    struct wlr_scene_output *m_scene_output = nullptr;
    std::array<struct wlr_scene_tree*, BWL_NR_LAYERS> m_layer_tree;
    struct wlr_scene_tree *m_layer_popup_tree;
    struct wlr_scene_tree *m_osd_tree;
    struct wlr_scene_tree *m_session_lock_tree;
    struct wlr_scene_buffer *m_workspace_osd;
    struct wlr_box m_usable_area;

    struct wl_list m_regions;  /* struct region.link */

    struct lab_data_buffer *m_osd_buffer;

    wl_listener_wrapper m_destroy;
    wl_listener_wrapper m_frame;
    wl_listener_wrapper m_request_state;

    bool m_leased;
    bool m_gamma_lut_changed;
    // struct wl_list m_outputs;
    // std::list<wl_listener_wrapper> m_outputs;
};
